/**
 * Copyright (c) 2019, Freqchip
 *
 * All rights reserved.
 *
 *
 */

/*
 * INCLUDES (����ͷ�ļ�)
 */
#include <stdio.h>
#include <string.h>
#include "gap_api.h"
#include "gatt_api.h"
#include "gatt_sig_uuid.h"
#include "sys_utils.h"
#include "os_task.h"

#include "hid_service.h"


/*
 * MACROS (�궨��)
 */
#define CFG_CON                     20

/*
 * CONSTANTS (��������)
 */
const uint8_t hid_svc_uuid[] = UUID16_ARR(HID_SERV_UUID);

// HID Information data
const uint8_t hid_info_value[] =
{
    LO_UINT16(0x0111), HI_UINT16(0x0111),             // bcdHID (USB HID version)
    0x00,                                             // bCountryCode
    HID_FLAGS_REMOTE_WAKE | HID_FLAGS_NORMALLY_CONNECTABLE     // Flags
};

/******************************* HID Report Map characteristic defination */

static const uint8_t hid_report_map_android[] =
{

    0x05, 0x0D,        // Usage Page (Digitizer)
0x09, 0x01,        // Usage (Digitizer)
0xA1, 0x01,        // Collection (Application)
0x85, 0x06,        //   Report ID (6)
0x09, 0x22,        //   Usage (Finger)
0xA1, 0x02,        //   Collection (Logical)
0x09, 0x42,        //     Usage (Tip Switch)
0x15, 0x00,        //     Logical Minimum (0)
0x25, 0x01,        //     Logical Maximum (1)
0x75, 0x01,        //     Report Size (1)
0x95, 0x01,        //     Report Count (1)
0x81, 0x02,        //     Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x09, 0x32,        //     Usage (In Range)
0x81, 0x02,        //     Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x95, 0x06,        //     Report Count (6)
0x81, 0x03,        //     Input (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x05, 0x01,        //     Usage Page (Generic Desktop Ctrls)
0x26, 0xFF, 0x0F,  //     Logical Maximum (4095)
0x75, 0x10,        //     Report Size (16)
0x95, 0x01,        //     Report Count (1)
0x55, 0x0E,        //     Unit Exponent (-2)
0x65, 0x33,        //     Unit (System: English Linear, Length: Inch)
0x09, 0x30,        //     Usage (X)
0x35, 0x00,        //     Physical Minimum (0)
0x46, 0xB5, 0x04,  //     Physical Maximum (1205)
0x81, 0x02,        //     Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x09, 0x31,        //     Usage (Y)
0x46, 0x8A, 0x03,  //     Physical Maximum (906)
0x81, 0x02,        //     Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0xC0,              //   End Collection
0xC0,              // End Collection


0x05, 0x0C,        // Usage Page (Consumer)
0x09, 0x01,        // Usage (Consumer Control)
0xA1, 0x01,        // Collection (Application)
0x85, 0x03,        //   Report ID (3)
0x15, 0x00,        //   Logical Minimum (0)
0x25, 0x01,        //   Logical Maximum (1)
0x75, 0x01,        //   Report Size (1)
#if 0
0x95, 0x05,        //   Report Count (5)
#else
0x95, 0x08,        //   Report Count (8)


#endif
0x09, 0xE9,        //   Usage (Volume Increment)
0x09, 0xEA,        //   Usage (Volume Decrement)
0x09, 0x30,        //   Usage (Power)
0x09, 0x40,        //   Usage (Menu)
0x0A, 0x23, 0x02,  //   Usage (AC Home)

#if 1
0x09, 0xB5,        //   Usage (Scan Previous Track)      // 【新增】Bit 5 - 上一曲 (0xB5)
0x09, 0xB6,        //   Usage (Scan Next Track)          // 【新增】Bit 6 - 下一曲 (0xB6)
0x09, 0xCD,        //   Usage (Play/Pause)               // 【新增】Bit 7 - 播放/暂停 (0xCD)
#endif
0x81, 0x06,        //   Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
0xC0,              // End Collection
0x05, 0x0C,        // Usage Page (Consumer)
0x09, 0x01,        // Usage (Consumer Control)
0xA1, 0x01,        // Collection (Application)
0x85, 0x02,        //   Report ID (2)
0x19, 0x00,        //   Usage Minimum (Unassigned)
0x2A, 0xFF, 0x03,  //   Usage Maximum (0x03FF)
0x15, 0x00,        //   Logical Minimum (0)
0x26, 0xFF, 0x03,  //   Logical Maximum (1023)
0x95, 0x01,        //   Report Count (1)
0x75, 0x10,        //   Report Size (16)
0x81, 0x00,        //   Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
0xC0,              // End Collection


};

static const uint8_t hid_report_map[] =
{
	
#if 0  //touch  new


0x05, 0x0D,        // Usage Page (Digitizers)
0x09, 0x05,        // Usage (Touch Pad)
0xA1, 0x01,        // Collection (Application)
0x85, 0x06,        //   Report ID (6)
0x09, 0x22,        //   Usage (Finger)
0xA1, 0x02,        //   Collection (Logical)
0x09, 0x42,        //     Usage (Tip Switch)
0x15, 0x00,        //     Logical Minimum (0)
0x25, 0x01,        //     Logical Maximum (1)
0x75, 0x01,        //     Report Size (1)
0x95, 0x01,        //     Report Count (1)
0x81, 0x02,        //     Input (Data,Var,Abs)
0x09, 0x32,        //     Usage (In Range)
0x75, 0x01,        //     Report Size (1)
0x95, 0x01,        //     Report Count (1)
0x81, 0x02,        //     Input (Data,Var,Abs)
0x75, 0x06,        //     Report Size (6)
0x95, 0x01,        //     Report Count (1)
0x81, 0x03,        //     Input (Const,Var,Abs)
0x05, 0x01,        //     Usage Page (Generic Desktop)
0x09, 0x30,        //     Usage (X)
0x16, 0x00, 0x00,  //     Logical Minimum (0)
0x26, 0xFF, 0x0F,  //     Logical Maximum (4095)
0x75, 0x10,        //     Report Size (16)
0x95, 0x01,        //     Report Count (1)
0x81, 0x02,        //     Input (Data,Var,Abs)
0x09, 0x31,        //     Usage (Y)
0x16, 0x00, 0x00,  //     Logical Minimum (0)
0x26, 0xFF, 0x0F,  //     Logical Maximum (4095)
0x75, 0x10,        //     Report Size (16)
0x95, 0x01,        //     Report Count (1)
0x81, 0x02,        //     Input (Data,Var,Abs)
0x05, 0x0D,        //     Usage Page (Digitizers)
0x09, 0x51,        //     Usage (Contact Identifier)
0x75, 0x08,        //     Report Size (8)
0x95, 0x01,        //     Report Count (1)
0x81, 0x02,        //     Input (Data,Var,Abs)
0xC0,              //   End Collection
0x05, 0x0D,        //   Usage Page (Digitizers)
0x09, 0x54,        //   Usage (Contact Count)
0x75, 0x08,        //   Report Size (8)
0x95, 0x01,        //   Report Count (1)
0x81, 0x02,        //   Input (Data,Var,Abs)
0xC0,               // End Collection


#else  //old
0x05, 0x0D,        // Usage Page (Digitizer)
0x09, 0x01,        // Usage (Digitizer)
0xA1, 0x01,        // Collection (Application)
0x85, 0x06,        //   Report ID (6)
0x09, 0x22,        //   Usage (Finger)
0xA1, 0x02,        //   Collection (Logical)
0x09, 0x42,        //     Usage (Tip Switch)
0x15, 0x00,        //     Logical Minimum (0)
0x25, 0x01,        //     Logical Maximum (1)
0x75, 0x01,        //     Report Size (1)
0x95, 0x01,        //     Report Count (1)
0x81, 0x02,        //     Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x09, 0x32,        //     Usage (In Range)
0x81, 0x02,        //     Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x95, 0x06,        //     Report Count (6)
0x81, 0x03,        //     Input (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x05, 0x01,        //     Usage Page (Generic Desktop Ctrls)
0x26, 0xFF, 0x0F,  //     Logical Maximum (4095)
0x75, 0x10,        //     Report Size (16)
0x95, 0x01,        //     Report Count (1)
0x55, 0x0E,        //     Unit Exponent (-2)
0x65, 0x33,        //     Unit (System: English Linear, Length: Inch)
0x09, 0x30,        //     Usage (X)
0x35, 0x00,        //     Physical Minimum (0)
0x46, 0xB5, 0x04,  //     Physical Maximum (1205)
0x81, 0x02,        //     Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x09, 0x31,        //     Usage (Y)
0x46, 0x8A, 0x03,  //     Physical Maximum (906)
0x81, 0x02,        //     Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0xC0,              //   End Collection
0xC0,              // End Collection
#endif

#if 0  //抓包前面的

0x05, 0x0C,        // Usage Page (Consumer)
0x09, 0x01,        // Usage (Consumer Control)
0xA1, 0x01,        // Collection (Application)
0x85, 0x03,        //   Report ID (3)
0x15, 0x00,        //   Logical Minimum (0)
0x25, 0x01,        //   Logical Maximum (1)
0x75, 0x01,        //   Report Size (1)
#if 0
0x95, 0x05,        //   Report Count (5)
#else
0x95, 0x08,        //   Report Count (8)


#endif
0x09, 0xE9,        //   Usage (Volume Increment)
0x09, 0xEA,        //   Usage (Volume Decrement)
0x09, 0x30,        //   Usage (Power)
0x09, 0x40,        //   Usage (Menu)
0x0A, 0x23, 0x02,  //   Usage (AC Home)
#if 1
0x09, 0xB5,        //   Usage (Scan Previous Track)      // 【新增】Bit 5 - 上一曲 (0xB5)
0x09, 0xB6,        //   Usage (Scan Next Track)          // 【新增】Bit 6 - 下一曲 (0xB6)
0x09, 0xCD,        //   Usage (Play/Pause)               // 【新增】Bit 7 - 播放/暂停 (0xCD)
#endif

0x81, 0x06,        //   Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
0xC0,              // End Collection
0x05, 0x0C,        // Usage Page (Consumer)
0x09, 0x01,        // Usage (Consumer Control)
0xA1, 0x01,        // Collection (Application)
0x85, 0x02,        //   Report ID (2)
0x19, 0x00,        //   Usage Minimum (Unassigned)
0x2A, 0xFF, 0x03,  //   Usage Maximum (0x03FF)
0x15, 0x00,        //   Logical Minimum (0)
0x26, 0xFF, 0x03,  //   Logical Maximum (1023)
0x95, 0x01,        //   Report Count (1)
0x75, 0x10,        //   Report Size (16)
0x81, 0x00,        //   Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
0xC0,              // End Collection
#else
//键盘发送的map

0x05, 0x0C,        // Usage Page (Consumer)
0x09, 0x01,        // Usage (Consumer Control)
0xA1, 0x01,        // Collection (Application)
0x85, 0x03,        //   Report ID (3)
0x15, 0x00,        //   Logical Minimum (0)
0x25, 0x01,        //   Logical Maximum (1)
0x75, 0x01,        //   Report Size (1)
0x95, 0x18,        //   Report Count (24)
0x09, 0x70,        //   Usage (0x70)
0x09, 0x6F,        //   Usage (0x6F)
0x0A, 0x21, 0x02,  //   Usage (AC Search)
0x0A, 0x92, 0x01,  //   Usage (AL Calculator)
0x0A, 0x06, 0x03,  //   Usage (0x0306)
0x0A, 0x07, 0x03,  //   Usage (0x0307)
0x09, 0xB6,        //   Usage (Scan Previous Track)
0x09, 0xCD,        //   Usage (Play/Pause)
0x09, 0xB5,        //   Usage (Scan Next Track)
0x09, 0xE2,        //   Usage (Mute)
0x09, 0xEA,        //   Usage (Volume Decrement)
0x09, 0xE9,        //   Usage (Volume Increment)
0x0A, 0x24, 0x02,  //   Usage (AC Back)
0x0A, 0x8A, 0x01,  //   Usage (AL Email Reader)
0x0A, 0xAE, 0x01,  //   Usage (AL Keyboard Layout)
0x0A, 0x23, 0x02,  //   Usage (AC Home)
0x0A, 0x96, 0x01,  //   Usage (AL Internet Browser)
0x0A, 0x92, 0x01,  //   Usage (AL Calculator)
0x0A, 0x94, 0x01,  //   Usage (AL Local Machine Browser)
0x0A, 0xB7, 0x00,  //   Usage (Stop)
0x0A, 0x2A, 0x02,  //   Usage (AC Bookmarks)
0x0A, 0x07, 0x03,  //   Usage (0x0307)
0x0A, 0x83, 0x01,  //   Usage (AL Consumer Control Configuration)
0x09, 0x30,        //   Usage (Power)
0x81, 0x02,        //   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0xC0,              // End Collection



#endif


#if 0

0x05, 0x01,        // Usage Page (Generic Desktop Ctrls)
0x09, 0x02,        // Usage (Mouse)
0xA1, 0x01,        // Collection (Application)
0x85, 0x01,        //   Report ID (1)
0x09, 0x01,        //   Usage (Pointer)
0xA1, 0x00,        //   Collection (Physical)
0x05, 0x09,        //     Usage Page (Button)
0x19, 0x01,        //     Usage Minimum (0x01)
0x29, 0x08,        //     Usage Maximum (0x08)
0x15, 0x00,        //     Logical Minimum (0)
0x25, 0x01,        //     Logical Maximum (1)
0x75, 0x01,        //     Report Size (1)
0x95, 0x08,        //     Report Count (8)
0x81, 0x02,        //     Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x05, 0x01,        //     Usage Page (Generic Desktop Ctrls)
0x09, 0x30,        //     Usage (X)
0x09, 0x31,        //     Usage (Y)

#if 1  //相对
0x16, 0x01, 0xF8,  //     Logical Minimum (-2047)
0x26, 0xFF, 0x07,  //     Logical Maximum (2047)
0x75, 0x10,        //     Report Size (16)
0x95, 0x02,        //     Report Count (2)
0x81, 0x06,        //     Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
#else 

// --- 关键修改开始：相对坐标改为绝对坐标 ---//绝对
0x16, 0x00,        //     Logical Minimum (0)          // 最小值改为0
0x26, 0xFF, 0x0F,  //     Logical Maximum (4095)       // 最大值改为4095（12位精度）
0x75, 0x10,        //     Report Size (16)             // 仍然使用16位存储
0x95, 0x02,        //     Report Count (2)
0x81, 0x02,        //     Input (Data,Var,Abs,...)     // Rel(0x06) -> Abs(0x02)
// --- 关键修改结束 ---
#endif
0x09, 0x38,        //     Usage (Wheel)
0x15, 0x81,        //     Logical Minimum (-127)
0x25, 0x7F,        //     Logical Maximum (127)
0x75, 0x08,        //     Report Size (8)
0x95, 0x01,        //     Report Count (1)
0x81, 0x06,        //     Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
0x05, 0x0C,        //     Usage Page (Consumer)
0x0A, 0x38, 0x02,  //     Usage (AC Pan)
0x95, 0x01,        //     Report Count (1)
0x81, 0x06,        //     Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
0xC0,              //   End Collection
0xC0,              // End Collection



#endif


#if   1   //ios 上报

//-----报告描述符--------------
#if 0  
//原配
0x05,0x01,          		//0   	GLOBAL_USAGE_PAGE(Generic Desktop Controls)	
0x09,0x02,          		//2   	LOCAL_USAGE(Mouse)	
0xA1,0x01,          		//4   	MAIN_COLLECTION(Applicatior)	
0x85,0x04,          		//6   	GLOBAL_REPORT_ID(4)	
0x09,0x01,          		//8   	LOCAL_USAGE(Pointer)	
0xA1,0x00,          		//10  	MAIN_COLLECTION(Physical)	
0x95,0x05,          		//12  	GLOBAL_REPORT_COUNT(5)	
0x75,0x01,          		//14  	GLOBAL_REPORT_SIZE(1)	
0x05,0x09,          		//16  	GLOBAL_USAGE_PAGE(Button)	
0x19,0x01,          		//18  	LOCAL_USAGE_MINIMUM(1)	
0x29,0x05,          		//20  	LOCAL_USAGE_MAXIMUM(5)	
0x15,0x00,          		//22  	GLOBAL_LOGICAL_MINIMUM(0)	
0x25,0x01,          		//24  	GLOBAL_LOCAL_MAXIMUM(1)	
0x81,0x02,          		//26  	MAIN_INPUT(data var absolute NoWrap linear PreferredState NoNullPosition NonVolatile )	Input 0.5
0x95,0x01,          		//28  	GLOBAL_REPORT_COUNT(1)	
0x75,0x03,          		//30  	GLOBAL_REPORT_SIZE(3)	
0x81,0x01,          		//32  	MAIN_INPUT(const array absolute NoWrap linear PreferredState NoNullPosition NonVolatile )	Input 1.0
0x75,0x08,          		//34  	GLOBAL_REPORT_SIZE(8)	
0x95,0x01,          		//36  	GLOBAL_REPORT_COUNT(1)	
0x05,0x01,          		//38  	GLOBAL_USAGE_PAGE(Generic Desktop Controls)	
0x09,0x38,          		//40  	LOCAL_USAGE(Wheel)	
0x15,0x81,          		//42  	GLOBAL_LOGICAL_MINIMUM(-127)	
0x25,0x7F,          		//44  	GLOBAL_LOCAL_MAXIMUM(127)	
0x81,0x06,          		//46  	MAIN_INPUT(data var relative NoWrap linear PreferredState NoNullPosition NonVolatile )	Input 2.0
0x05,0x0C,          		//48  	GLOBAL_USAGE_PAGE(Consumer)	
0x0A,0x38,0x02,     		//50  	LOCAL_USAGE(	AC Pan 	)	
0x95,0x01,          		//53  	GLOBAL_REPORT_COUNT(1)	
0x81,0x06,          		//55  	MAIN_INPUT(data var relative NoWrap linear PreferredState NoNullPosition NonVolatile )	Input 3.0
0xC0,               		//57  	MAIN_COLLECTION_END	
#else
//修改按键8个
0x05,0x01,          		// GLOBAL_USAGE_PAGE(Generic Desktop Controls)	
0x09,0x02,          		// LOCAL_USAGE(Mouse)	
0xA1,0x01,          		// MAIN_COLLECTION(Application)	
0x85,0x04,          		// GLOBAL_REPORT_ID(4)	
0x09,0x01,          		// LOCAL_USAGE(Pointer)	
0xA1,0x00,          		// MAIN_COLLECTION(Physical)	

// 修改部分开始
0x95,0x08,          		// GLOBAL_REPORT_COUNT(8)   // 改为8个按钮
0x75,0x01,          		// GLOBAL_REPORT_SIZE(1)	
0x05,0x09,          		// GLOBAL_USAGE_PAGE(Button)	
0x19,0x01,          		// LOCAL_USAGE_MINIMUM(1)	
0x29,0x08,          		// LOCAL_USAGE_MAXIMUM(8)   // 最大值改为8
0x15,0x00,          		// GLOBAL_LOGICAL_MINIMUM(0)	
0x25,0x01,          		// GLOBAL_LOGICAL_MAXIMUM(1)	
0x81,0x02,          		// MAIN_INPUT(Data, Var, Abs)
// 移除了原来的填充位部分
// 修改部分结束

0x75,0x08,          		// GLOBAL_REPORT_SIZE(8)	
0x95,0x01,          		// GLOBAL_REPORT_COUNT(1)	
0x05,0x01,          		// GLOBAL_USAGE_PAGE(Generic Desktop Controls)	
0x09,0x38,          		// LOCAL_USAGE(Wheel)	
0x15,0x81,          		// GLOBAL_LOGICAL_MINIMUM(-127)	
0x25,0x7F,          		// GLOBAL_LOGICAL_MAXIMUM(127)	
0x81,0x06,          		// MAIN_INPUT(Data, Var, Rel)
0x05,0x0C,          		// GLOBAL_USAGE_PAGE(Consumer)	
0x0A,0x38,0x02,     		// LOCAL_USAGE(AC Pan)	
0x95,0x01,          		// GLOBAL_REPORT_COUNT(1)	
0x81,0x06,          		// MAIN_INPUT(Data, Var, Rel)
0xC0,               		// MAIN_COLLECTION_END

#endif
#if 1   //ios 附加的
0x85,0x05,          		//58  	GLOBAL_REPORT_ID(5)	
0x09,0x01,          		//60  	LOCAL_USAGE(	Consumer Control 	)	
0xA1,0x00,          		//62  	MAIN_COLLECTION(Physical)	
0x75,0x0C,          		//64  	GLOBAL_REPORT_SIZE(12)	
0x95,0x02,          		//66  	GLOBAL_REPORT_COUNT(2)	
0x05,0x01,          		//68  	GLOBAL_USAGE_PAGE(Generic Desktop Controls)	
0x09,0x30,          		//70  	LOCAL_USAGE(X)	
0x09,0x31,          		//72  	LOCAL_USAGE(Y)	
0x16,0x01,0xF8,     		//74  	GLOBAL_LOGICAL_MINIMUM(-2047)  // 修复：从错误的504改为正确的-2047
0x26,0xFF,0x07,     		//77  	GLOBAL_LOGICAL_MAXIMUM(2047)	
0x81,0x06,          		//80  	MAIN_INPUT(data var relative NoWrap linear PreferredState NoNullPosition NonVolatile )	Input 6.0
0xC0,               		//82  	MAIN_COLLECTION_END	
0xC0,               		//83  	MAIN_COLLECTION_END	

#if 0
0x05, 0x0D,        // Usage Page (Digitizer)
0x09, 0x02,        // Usage (Pen)
0xA1, 0x01,        // Collection (Application)
0x85, 0x01,        //   Report ID (1)
0x09, 0x22,        //   Usage (Finger)
0xA1, 0x02,        //   Collection (Logical)
0x09, 0x42,        //     Usage (Tip Switch)
0x15, 0x00,        //     Logical Minimum (0)
0x25, 0x01,        //     Logical Maximum (1)
0x75, 0x01,        //     Report Size (1)
0x95, 0x01,        //     Report Count (1)
0x81, 0x02,        //     Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x09, 0x32,        //     Usage (In Range)
0x81, 0x02,        //     Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x95, 0x06,        //     Report Count (6)
0x81, 0x03,        //     Input (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x75, 0x08,        //     Report Size (8)
0x09, 0x51,        //     Usage (0x51)
0x95, 0x01,        //     Report Count (1)
0x81, 0x02,        //     Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x05, 0x01,        //     Usage Page (Generic Desktop Ctrls)
0x26, 0xFF, 0x0F,  //     Logical Maximum (4095)
0x75, 0x10,        //     Report Size (16)
0x55, 0x0E,        //     Unit Exponent (-2)
0x65, 0x33,        //     Unit (System: English Linear, Length: Inch)
0x09, 0x30,        //     Usage (X)
0x35, 0x00,        //     Physical Minimum (0)
0x46, 0xB5, 0x04,  //     Physical Maximum (1205)
0x81, 0x02,        //     Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x46, 0x8A, 0x03,  //     Physical Maximum (906)
0x09, 0x31,        //     Usage (Y)
0x81, 0x02,        //     Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0xC0,              //   End Collection
0x05, 0x0D,        //   Usage Page (Digitizer)
0x09, 0x54,        //   Usage (0x54)
0x95, 0x01,        //   Report Count (1)
0x75, 0x08,        //   Report Size (8)
0x81, 0x02,        //   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x85, 0x08,        //   Report ID (8)
0x09, 0x55,        //   Usage (0x55)
0x25, 0x05,        //   Logical Maximum (5)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0xC0,              // End Collection

// 87 bytes

// best guess: USB HID Report Descriptor

#else

0x05, 0x0D,        // Usage Page (Digitizer)
0x09, 0x02,        // Usage (Pen)
0xA1, 0x01,        // Collection (Application)
0x85, 0x01,        //   Report ID (1)
0x09, 0x22,        //   Usage (Finger)
0xA1, 0x02,        //   Collection (Logical)
0x09, 0x42,        //     Usage (Tip Switch)
0x15, 0x00,        //     Logical Minimum (0)
0x25, 0x01,        //     Logical Maximum (1)
0x75, 0x01,        //     Report Size (1)
0x95, 0x01,        //     Report Count (1)
0x81, 0x02,        //     Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x09, 0x32,        //     Usage (In Range)
0x81, 0x02,        //     Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x95, 0x06,        //     Report Count (6)
0x81, 0x03,        //     Input (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x75, 0x08,        //     Report Size (8)
0x09, 0x51,        //     Usage (0x51)
0x95, 0x01,        //     Report Count (1)
0x81, 0x02,        //     Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x05, 0x01,        //     Usage Page (Generic Desktop Ctrls)
0x26, 0xFF, 0x0F,  //     Logical Maximum (4095)
0x75, 0x10,        //     Report Size (16)
0x55, 0x0E,        //     Unit Exponent (-2)
0x65, 0x33,        //     Unit (System: English Linear, Length: Inch)
0x09, 0x30,        //     Usage (X)
0x35, 0x00,        //     Physical Minimum (0)
0x46, 0xB5, 0x04,  //     Physical Maximum (1205)
0x81, 0x02,        //     Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x46, 0x8A, 0x03,  //     Physical Maximum (906)
0x09, 0x31,        //     Usage (Y)
0x81, 0x02,        //     Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0xC0,              //   End Collection
0x05, 0x0D,        //   Usage Page (Digitizer)
0x09, 0x54,        //   Usage (0x54)
0x95, 0x01,        //   Report Count (1)
0x75, 0x08,        //   Report Size (8)
0x81, 0x02,        //   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x85, 0x08,        //   Report ID (8)
0x09, 0x55,        //   Usage (0x55)
0x25, 0x05,        //   Logical Maximum (5)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0xC0,              // End Collection



#endif


#else
0xC0,               		//83  	MAIN_COLLECTION_END	
#endif


#endif

};
/******************************* External Report Reference defination */
// External Report Reference Descriptor UUID
const uint8_t ext_report_ref_uuid[] = UUID16_ARR(0x00);


uint8_t hid_svc_id = 0;

// HID report information table
static hid_report_ref_t  hid_rpt_info[HID_NUM_REPORTS];
static bool hid_link_ntf_enable[CFG_CON] = {0};
static bool hid_link_enable[CFG_CON] = {0};
/*
 * TYPEDEFS (���Ͷ���)
 */


/*
 * EXTERNAL VARIABLES (�ⲿ����)
 */

/*
 * GLOBAL VARIABLES (ȫ�ֱ���)
 */


/*
 * LOCAL VARIABLES (���ر���)
 */

/*********************************************************************
 * Profile Attributes - Table
 * ÿһ���һ��attribute�Ķ��塣
 * ��һ��attributeΪService �ĵĶ��塣
 * ÿһ������ֵ(characteristic)�Ķ��壬�����ٰ�������attribute�Ķ��壻
 * 1. ����ֵ����(Characteristic Declaration)
 * 2. ����ֵ��ֵ(Characteristic value)
 * 3. ����ֵ������(Characteristic description)
 * �����notification ����indication �Ĺ��ܣ��������ĸ�attribute�Ķ��壬����ǰ�涨���������������һ������ֵ�ͻ�������(client characteristic configuration)��
 *
 */
const gatt_attribute_t hid_profile_att_table[] =
{
    [HID_SERVICE_IDX]               =   { 
                                            { UUID_SIZE_2, UUID16_ARR(GATT_PRIMARY_SERVICE_UUID) },
                                            GATT_PROP_READ, 
                                            UUID_SIZE_2, 
                                            (uint8_t *)hid_svc_uuid,
                                        },

#if ((HID_DEV & HID_DEV_MAP_EXT_REF) == HID_DEV_MAP_EXT_REF)
    //[HID_INCLUDED_SERVICE_IDX]      =   { 
    //                                        { UUID_SIZE_2, UUID16_ARR(GATT_INCLUDE_UUID) },
    //                                        GATT_PROP_READ,
    //                                        0,
    //                                        NULL,
    //                                    },
#endif //((HID_DEV & HID_DEV_MAP_EXT_REF) == HID_DEV_MAP_EXT_REF)

    [HID_INFO_DECL_IDX]             =   { 
                                            { UUID_SIZE_2, UUID16_ARR(GATT_CHARACTER_UUID) },
                                            GATT_PROP_READ,
                                            0, 
                                            NULL,
                                        },
    
    [HID_INFO_IDX]                  =   { 
                                            { UUID_SIZE_2, UUID16_ARR(HID_INFORMATION_UUID) },
                                            GATT_PROP_READ | GATT_PROP_AUTHEN,     //GATT_PROP_AUTHEN
                                            sizeof(hid_info_value), 
                                            NULL,
                                        },


    // HID Control Point characteristic declaration
    [HID_CONTROL_POINT_DECL_IDX]    =   { 
                                            { UUID_SIZE_2, UUID16_ARR(GATT_CHARACTER_UUID) },
                                            GATT_PROP_READ, 
                                            0,
                                            NULL,
                                        },
                                        
    // HID Control Point characteristic value
    [HID_CONTROL_POINT_IDX]         =   { 
                                            { UUID_SIZE_2, UUID16_ARR(HID_CTRL_PT_UUID) },
                                            GATT_PROP_WRITE, 
                                            sizeof(uint8_t), 
                                            NULL,
                                        },

    // HID Report Map characteristic declaration
    [HID_REPORT_MAP_DECL_IDX]       =   { 
                                            { UUID_SIZE_2, UUID16_ARR(GATT_CHARACTER_UUID) },
                                            GATT_PROP_READ, 
                                            0, 
                                            NULL,
                                        },

    // HID Report Map characteristic
    [HID_REPORT_MAP_IDX]            =   { 
                                            { UUID_SIZE_2, UUID16_ARR(REPORT_MAP_UUID) },
                                            GATT_PROP_READ,  
                                            512, 
                                            NULL,
                                        },

 // HID Protocol Mode characteristic declaration
 [HID_PROTOCOL_MODE_DECL_IDX]    =   { 
    { UUID_SIZE_2, UUID16_ARR(GATT_CHARACTER_UUID) },
    GATT_PROP_READ, 
    0,
    NULL,
},

// HID Protocol Mode characteristic
[HID_PROTOCOL_MODE_IDX]         =   { 
    { UUID_SIZE_2, UUID16_ARR(PROTOCOL_MODE_UUID) },
    GATT_PROP_READ | GATT_PROP_WRITE, 
    sizeof(uint8_t),
    NULL,
},

// HID Feature Report No 0
    [HID_FEATURE_DECL_IDX]          =   { 
                                            { UUID_SIZE_2, UUID16_ARR(GATT_CHARACTER_UUID) },
                                            GATT_PROP_READ, 
                                            0,
                                            NULL,
                                        },
                                        
    [HID_FEATURE_IDX]               =   { 
                                            { UUID_SIZE_2, UUID16_ARR(REPORT_UUID) },
                                            GATT_PROP_READ | GATT_PROP_NOTI,
                                            60,
                                            NULL,
                                        },
                                        
    [HID_REPORT_REF_FEATURE_IDX]    =   { 
                                            { UUID_SIZE_2, UUID16_ARR(GATT_REPORT_REF_UUID) },
                                            GATT_PROP_READ,
                                            sizeof(hid_report_ref_t), 
                                            NULL,
                                        },
                                        
    [HID_FEATURE_CCCD_IDX]          =   { 
                                            { UUID_SIZE_2, UUID16_ARR(GATT_CLIENT_CHAR_CFG_UUID) },
                                            GATT_PROP_READ | GATT_PROP_WRITE, 
                                            0, 
                                            NULL,
                                        },

    // HID Feature Report No 1
    [HID_FEATURE_DECL_IDX + 4 * 1]          =   { 
                                                    { UUID_SIZE_2, UUID16_ARR(GATT_CHARACTER_UUID) },
                                                    GATT_PROP_READ, 
                                                    0,
                                                    NULL,
                                                },
                                        
    [HID_FEATURE_IDX + 4 * 1]               =   { 
                                                    { UUID_SIZE_2, UUID16_ARR(REPORT_UUID) },
                                                    GATT_PROP_READ | GATT_PROP_NOTI,
                                                    60,
                                                    NULL,
                                                },
                                        
    [HID_REPORT_REF_FEATURE_IDX + 4 * 1]    =   { 
                                                    { UUID_SIZE_2, UUID16_ARR(GATT_REPORT_REF_UUID) },
                                                    GATT_PROP_READ,
                                                    sizeof(hid_report_ref_t), 
                                                    NULL,
                                                },
                                                
    [HID_FEATURE_CCCD_IDX + 4 * 1]          =   { 
                                                    { UUID_SIZE_2, UUID16_ARR(GATT_CLIENT_CHAR_CFG_UUID) },
                                                    GATT_PROP_READ | GATT_PROP_WRITE, 
                                                    0, 
                                                    NULL,
                                                },

    // HID Feature Report No 2
    [HID_FEATURE_DECL_IDX + 4 * 2]          =   { 
                                                    { UUID_SIZE_2, UUID16_ARR(GATT_CHARACTER_UUID) },
                                                    GATT_PROP_READ, 
                                                    0,
                                                    NULL,
                                                },
                                                
    [HID_FEATURE_IDX + 4 * 2]               =   { 
                                                    { UUID_SIZE_2, UUID16_ARR(REPORT_UUID) },
                                                    GATT_PROP_READ | GATT_PROP_NOTI,
                                                    60,
                                                    NULL,
                                                },
                                                
    [HID_REPORT_REF_FEATURE_IDX + 4 * 2]    =   { 
                                                    { UUID_SIZE_2, UUID16_ARR(GATT_REPORT_REF_UUID) },
                                                    GATT_PROP_READ,
                                                    sizeof(hid_report_ref_t), 
                                                    NULL,
                                                },
                                                
    [HID_FEATURE_CCCD_IDX + 4 * 2]          =   { 
                                                    { UUID_SIZE_2, UUID16_ARR(GATT_CLIENT_CHAR_CFG_UUID) },
                                                    GATT_PROP_READ | GATT_PROP_WRITE, 
                                                    0, 
                                                    NULL,
                                                },

    // HID Feature Report No 3
    [HID_FEATURE_DECL_IDX + 4 * 3]          =   { 
                                                    { UUID_SIZE_2, UUID16_ARR(GATT_CHARACTER_UUID) },
                                                    GATT_PROP_READ, 
                                                    0,
                                                    NULL,
                                                },
                                                
    [HID_FEATURE_IDX + 4 * 3]               =   { 
                                                    { UUID_SIZE_2, UUID16_ARR(REPORT_UUID) },
                                                    GATT_PROP_READ | GATT_PROP_WRITE | GATT_PROP_NOTI,
                                                    60,
                                                    NULL,
                                                },
                                                
    [HID_REPORT_REF_FEATURE_IDX + 4 * 3]    =   { 
                                                    { UUID_SIZE_2, UUID16_ARR(GATT_REPORT_REF_UUID) },
                                                    GATT_PROP_READ,
                                                    sizeof(hid_report_ref_t), 
                                                    NULL,
                                                },
                                                
    [HID_FEATURE_CCCD_IDX + 4 * 3]          =   { 
                                                    { UUID_SIZE_2, UUID16_ARR(GATT_CLIENT_CHAR_CFG_UUID) },
                                                    GATT_PROP_READ | GATT_PROP_WRITE, 
                                                    0, 
                                                    NULL,
                                                },

    // HID Feature Report No 4
    [HID_FEATURE_DECL_IDX + 4 * 4]          =   { 
        { UUID_SIZE_2, UUID16_ARR(GATT_CHARACTER_UUID) },
        GATT_PROP_READ, 
        0,
        NULL,
    },
    [HID_FEATURE_IDX + 4 * 4]               =   { 
        { UUID_SIZE_2, UUID16_ARR(REPORT_UUID) },
        GATT_PROP_READ | GATT_PROP_NOTI,
        60,
        NULL,
    },
    [HID_REPORT_REF_FEATURE_IDX + 4 * 4]    =   { 
        { UUID_SIZE_2, UUID16_ARR(GATT_REPORT_REF_UUID) },
        GATT_PROP_READ,
        sizeof(hid_report_ref_t), 
        NULL,
    },
    [HID_FEATURE_CCCD_IDX + 4 * 4]          =   { 
        { UUID_SIZE_2, UUID16_ARR(GATT_CLIENT_CHAR_CFG_UUID) },
        GATT_PROP_READ | GATT_PROP_WRITE, 
        0, 
        NULL,
    },


       // HID Feature Report No 5
       [HID_FEATURE_DECL_IDX + 5 * 4]          =   { 
        { UUID_SIZE_2, UUID16_ARR(GATT_CHARACTER_UUID) },
        GATT_PROP_READ, 
        0,
        NULL,
    },
    [HID_FEATURE_IDX + 5 * 4]               =   { 
        { UUID_SIZE_2, UUID16_ARR(REPORT_UUID) },
        GATT_PROP_READ | GATT_PROP_NOTI,
        60,
        NULL,
    },
    [HID_REPORT_REF_FEATURE_IDX + 5 * 4]    =   { 
        { UUID_SIZE_2, UUID16_ARR(GATT_REPORT_REF_UUID) },
        GATT_PROP_READ,
        sizeof(hid_report_ref_t), 
        NULL,
    },
    [HID_FEATURE_CCCD_IDX + 5 * 4]          =   { 
        { UUID_SIZE_2, UUID16_ARR(GATT_CLIENT_CHAR_CFG_UUID) },
        GATT_PROP_READ | GATT_PROP_WRITE, 
        0, 
        NULL,
    },

       // HID Feature Report No 6
       [HID_FEATURE_DECL_IDX + 6 * 4]          =   { 
        { UUID_SIZE_2, UUID16_ARR(GATT_CHARACTER_UUID) },
        GATT_PROP_READ, 
        0,
        NULL,
    },
    [HID_FEATURE_IDX + 6 * 4]               =   { 
        { UUID_SIZE_2, UUID16_ARR(REPORT_UUID) },
        GATT_PROP_READ | GATT_PROP_NOTI,
        60,
        NULL,
    },
    [HID_REPORT_REF_FEATURE_IDX + 6 * 4]    =   { 
        { UUID_SIZE_2, UUID16_ARR(GATT_REPORT_REF_UUID) },
        GATT_PROP_READ,
        sizeof(hid_report_ref_t), 
        NULL,
    },
    [HID_FEATURE_CCCD_IDX + 6 * 4]          =   { 
        { UUID_SIZE_2, UUID16_ARR(GATT_CLIENT_CHAR_CFG_UUID) },
        GATT_PROP_READ | GATT_PROP_WRITE, 
        0, 
        NULL,
    },






    // HID Feature Report No 7
    [HID_FEATURE_DECL_IDX + 7 * 4]          =   { 
        { UUID_SIZE_2, UUID16_ARR(GATT_CHARACTER_UUID) },
        GATT_PROP_READ, 
        0,
        NULL,
    },
    [HID_FEATURE_IDX + 7 * 4]               =   { 
        { UUID_SIZE_2, UUID16_ARR(REPORT_UUID) },
        GATT_PROP_READ | GATT_PROP_NOTI,
        60,
        NULL,
    },
    [HID_REPORT_REF_FEATURE_IDX + 7 * 4]    =   { 
        { UUID_SIZE_2, UUID16_ARR(GATT_REPORT_REF_UUID) },
        GATT_PROP_READ,
        sizeof(hid_report_ref_t), 
        NULL,
    },
    [HID_FEATURE_CCCD_IDX + 7 * 4]          =   { 
        { UUID_SIZE_2, UUID16_ARR(GATT_CLIENT_CHAR_CFG_UUID) },
        GATT_PROP_READ | GATT_PROP_WRITE, 
        0, 
        NULL,
    },








        // HID Feature Report No 8
        [HID_FEATURE_DECL_IDX + 8 * 4]          =   { 
            { UUID_SIZE_2, UUID16_ARR(GATT_CHARACTER_UUID) },
            GATT_PROP_READ, 
            0,
            NULL,
        },
        [HID_FEATURE_IDX + 8 * 4]               =   { 
            { UUID_SIZE_2, UUID16_ARR(REPORT_UUID) },
            GATT_PROP_READ | GATT_PROP_NOTI,
            60,
            NULL,
        },
        [HID_REPORT_REF_FEATURE_IDX + 8 * 4]    =   { 
            { UUID_SIZE_2, UUID16_ARR(GATT_REPORT_REF_UUID) },
            GATT_PROP_READ,
            sizeof(hid_report_ref_t), 
            NULL,
        },
        [HID_FEATURE_CCCD_IDX + 8 * 4]          =   { 
            { UUID_SIZE_2, UUID16_ARR(GATT_CLIENT_CHAR_CFG_UUID) },
            GATT_PROP_READ | GATT_PROP_WRITE, 
            0, 
            NULL,
        },




                // HID Feature Report No 9
                [HID_FEATURE_DECL_IDX + 9 * 4]          =   { 
                    { UUID_SIZE_2, UUID16_ARR(GATT_CHARACTER_UUID) },
                    GATT_PROP_READ, 
                    0,
                    NULL,
                },
                [HID_FEATURE_IDX + 9 * 4]               =   { 
                    { UUID_SIZE_2, UUID16_ARR(REPORT_UUID) },
                    GATT_PROP_READ | GATT_PROP_NOTI,
                    60,
                    NULL,
                },
                [HID_REPORT_REF_FEATURE_IDX + 9 * 4]    =   { 
                    { UUID_SIZE_2, UUID16_ARR(GATT_REPORT_REF_UUID) },
                    GATT_PROP_READ,
                    sizeof(hid_report_ref_t), 
                    NULL,
                },
                [HID_FEATURE_CCCD_IDX + 9 * 4]          =   { 
                    { UUID_SIZE_2, UUID16_ARR(GATT_CLIENT_CHAR_CFG_UUID) },
                    GATT_PROP_READ | GATT_PROP_WRITE, 
                    0, 
                    NULL,
                },
};


/*********************************************************************
 * @fn      hid_gatt_op_cmp_handler
 *
 * @brief   Gatt operation complete handler.
 *
 *
 * @param   p_operation  - operation that has compeleted
 *
 * @return  none.
 */
void hid_gatt_op_cmp_handler(gatt_op_cmp_t *p_operation)
{
    if (p_operation->status == 0)
    {}
}

/*********************************************************************
 * @fn      hid_gatt_msg_handler
 *
 * @brief   HID gatt message handler.
 *
 *
 * @param   p_msg  - messages from GATT layer.
 *
 * @return  none.
 */
static uint16_t hid_gatt_msg_handler(gatt_msg_t *p_msg)
{
    switch(p_msg->msg_evt)
    {
        case GATTC_MSG_READ_REQ:
            //if(hid_link_enable[p_msg->conn_idx] == false)
               // return 0xffff;  //save this msg
                
            if(p_msg->att_idx == HID_REPORT_MAP_IDX)
            {

                extern bool ios_devices;
         




                if(ios_devices)
               { co_printf("report_ios map request:%d\r\n",sizeof(hid_report_map));
                memcpy(p_msg->param.msg.p_msg_data, hid_report_map, sizeof(hid_report_map));
                return sizeof(hid_report_map);
               }else
               {

                co_printf("report_android map request:%d\r\n",sizeof(hid_report_map_android));
                memcpy(p_msg->param.msg.p_msg_data, hid_report_map_android, sizeof(hid_report_map_android));
                return sizeof(hid_report_map_android);
               }
                

        
            }
            else if (p_msg->att_idx == HID_INFO_IDX)
            {
                co_printf("hid info request\r\n");
                memcpy(p_msg->param.msg.p_msg_data, hid_info_value, sizeof(hid_info_value));
                return sizeof(hid_info_value);
            }
            else
            {
                for(uint8_t idx=0; idx<HID_NUM_REPORTS; idx++)
                {
                    if(p_msg->att_idx == HID_REPORT_REF_FEATURE_IDX + 4 * idx)
                    {
                        co_printf("report_ref[%d] request\r\n",idx);
                        memcpy(p_msg->param.msg.p_msg_data, (uint8_t *)&hid_rpt_info[idx], sizeof(hid_report_ref_t));
                        return sizeof(hid_report_ref_t);
                    }
                }
            }
            break;

        case GATTC_MSG_WRITE_REQ:
            //if(hid_link_enable[p_msg->conn_idx] == false)
                //return 0xffff;  //save this msg

//            if(p_msg->att_idx == HID_BOOT_KEY_IN_CCCD_IDX)
//            {
//                co_printf("boot_key_ntf_enable:");
//                show_reg(p_msg->param.msg.p_msg_data,p_msg->param.msg.msg_len,1);
//            }
//            else 
							
						if(p_msg->att_idx == HID_FEATURE_IDX + 4 * 3)
            {
                co_printf("write report_id 3:");
                show_reg(p_msg->param.msg.p_msg_data,p_msg->param.msg.msg_len,1);
                uint8_t *data = p_msg->param.msg.p_msg_data;
                if(data[0] & (1<<0))
                    co_printf("num_lock on\r\n");
                else
                    co_printf("num_lock off\r\n");
                if (data[0] & (1<<1))
                    co_printf("caps_lock on\r\n");
                else
                    co_printf("caps_lock off\r\n");
                hid_link_ntf_enable[p_msg->conn_idx] = true;
            }
            else
            {


                if(p_msg->att_idx == HID_FEATURE_CCCD_IDX + 4 * 8){


                    // gap_conn_param_update(0, 80, 80, 4, 2000); //→ 100–200 ms，latency 4（能大幅省电）

                    //gap_conn_param_update(0, 24, 48, 0, 600);

                    // gap_conn_param_update(0, 80, 160, 4, 600); //→ 100–200 ms，latency 4（能大幅省电）
                    //extern bool ios_devices;
                    //if(ios_devices){
                    //gap_conn_param_update(0, 64, 64, 4, 600);
//
                    //}else
                    //gap_conn_param_update(0, 80, 80, 4, 2000); //→ 100–200 ms，latency 4（能大幅省电）

                }

                for(uint8_t idx=0; idx<HID_NUM_REPORTS; idx++)
                {
                    if(p_msg->att_idx == HID_FEATURE_CCCD_IDX + 4 * idx)
                    {
                        co_printf("ntf_enable[%d]:",idx);
                        show_reg(p_msg->param.msg.p_msg_data,p_msg->param.msg.msg_len,1);


                            if(idx == 8)
                        {
                            //初始化完成 上报初始位置
                            extern void  reset_init_poszation(bool start_timer);
                            reset_init_poszation(true);
                        }
                    }
                    if(idx == 2)
                        hid_link_ntf_enable[p_msg->conn_idx] = true;
                    
                }

          
            }
            break;

        case GATTC_MSG_CMP_EVT:
            hid_gatt_op_cmp_handler((gatt_op_cmp_t*)&(p_msg->param.op));
            break;
        case GATTC_MSG_LINK_CREATE:
            //co_printf("link[%d] create\r\n",p_msg->conn_idx);
            hid_link_ntf_enable[p_msg->conn_idx] = true;
            break;
        case GATTC_MSG_LINK_LOST:
            //co_printf("link[%d] lost\r\n",p_msg->conn_idx);
            hid_link_ntf_enable[p_msg->conn_idx] = false;
            hid_link_enable[p_msg->conn_idx] = false;
            break;
        default:
            break;
    }
    return 0;
}
void hid_service_enable(uint8_t conidx)
{
    //hid_link_enable[conidx] = true;
    //os_task_process_saved_msg(gatt_get_task_no_from_prf_id(hid_svc_id));
}

/*********************************************************************
 * @fn      hid_gatt_report_notify
 *
 * @brief   Send HID notification, keys, mouse values, etc.
 *
 *
 * @param   rpt_info_id - report idx of the hid_rpt_info array.
 *          len         - length of the HID information data.
 *          p_data      - data of the HID information to be sent.
 *
 * @return  none.
 */
void hid_gatt_report_notify(uint8_t conidx, uint8_t rpt_info_id, uint8_t *p_data, uint16_t len)
{
    if (rpt_info_id < HID_NUM_REPORTS && hid_link_ntf_enable[conidx])
    {
        gatt_ntf_t ntf;
        ntf.conidx = conidx;
        ntf.svc_id = hid_svc_id;
        ntf.att_idx = HID_FEATURE_IDX + 4*(rpt_info_id) ;
        ntf.data_len = len;
        ntf.p_data = p_data;
        gatt_notification(ntf);
    }
}

/*********************************************************************
 * @fn      hid_gatt_add_service
 *
 * @brief   Simple Profile add GATT service function.
 *          ����GATT service��ATT�����ݿ����档
 *
 * @param   None.
 *
 *
 * @return  None.
 */
void hid_gatt_add_service(void)
{
    gatt_service_t hid_profie_svc;

    hid_profie_svc.p_att_tb = hid_profile_att_table;
    hid_profie_svc.att_nb = HID_ATT_NB;
    hid_profie_svc.gatt_msg_handler = hid_gatt_msg_handler;

    hid_rpt_info[0].report_id = 1;     //refer to report map, this is Mouse
    hid_rpt_info[0].report_type = HID_REPORT_TYPE_INPUT;

    hid_rpt_info[1].report_id = 2;      //refer to report map, this is Cosumer Controller
    hid_rpt_info[1].report_type = HID_REPORT_TYPE_INPUT;

    hid_rpt_info[2].report_id = 3;      //refer to report map, this is Keyboard input.
    hid_rpt_info[2].report_type = HID_REPORT_TYPE_INPUT;     //att_table, perm must be GATT_PROP_READ | GATT_PROP_NOTI

    hid_rpt_info[3].report_id = 4;      //refer to report map, this is Keyboard output.
    hid_rpt_info[3].report_type = HID_REPORT_TYPE_INPUT;   //att_table, perm must be GATT_PROP_READ | GATT_PROP_WRITE


    hid_rpt_info[4].report_id = 5;      //refer to report map, this is Keyboard output.
    hid_rpt_info[4].report_type = HID_REPORT_TYPE_INPUT /*HID_REPORT_TYPE_INPUT*/;   //att_table, perm must be GATT_PROP_READ | GATT_PROP_WRITE


    hid_rpt_info[5].report_id = 6;      //refer to report map, this is Keyboard output.
    hid_rpt_info[5].report_type = HID_REPORT_TYPE_INPUT;   //att_table, perm must be GATT_PROP_READ | GATT_PROP_WRITE


    hid_rpt_info[6].report_id = 7;      //refer to report map, this is Keyboard output.
    hid_rpt_info[6].report_type = HID_REPORT_TYPE_INPUT;   //att_table, perm must be GATT_PROP_READ | GATT_PROP_WRITE


    hid_rpt_info[7].report_id = 8;      //refer to report map, this is Keyboard output.
    hid_rpt_info[7].report_type = HID_REPORT_TYPE_INPUT;   //att_table, perm must be GATT_PROP_READ | GATT_PROP_WRITE


    hid_rpt_info[8].report_id = 9;      //refer to report map, this is Keyboard output.
    hid_rpt_info[8].report_type = HID_REPORT_TYPE_INPUT;   //att_table, perm must be GATT_PROP_READ | GATT_PROP_WRITE


    // 新增Touch输入报告
    #if 0
    hid_rpt_info[4].report_id = 4;      // Touch (Digitizer)
    hid_rpt_info[4].report_type = HID_REPORT_TYPE_INPUT;
    #endif

    hid_svc_id = gatt_add_service(&hid_profie_svc);
}





